package com.lagou.zk.load;

import com.alibaba.druid.pool.DruidDataSource;
import com.lagou.zk.utils.SpringUtils;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.RetryNTimes;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

/**
 * 启动加载数据
 */
@Component
public class DataSourceConfigForZk implements ApplicationListener<ContextRefreshedEvent> {

    private static final String CONFIG_PREFIX = "/CONFIG";
    private static final String DRIVER_CLASS = "/DRIVER_CLASS";
    private static final String URL = "/URL";
    private static final String USERNAME = "/USERNAME";
    private static final String PASSWORD = "/PASSWORD";

    /**
     * 构造函数 .
     */
    public void init() {
        try {
            CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", new RetryNTimes(3, 1000));
            client.start();
            // 从zk中获取配置项并保存到缓存中
            reloadDataSource(new String(client.getData().forPath(CONFIG_PREFIX + DRIVER_CLASS)),
                    new String(client.getData().forPath(CONFIG_PREFIX + URL)),
                    new String(client.getData().forPath(CONFIG_PREFIX + USERNAME)),
                    new String(client.getData().forPath(CONFIG_PREFIX + PASSWORD)));
            
            
            // 使用该配置文件的每个应用机器都需要监听
            PathChildrenCache watcher = new PathChildrenCache(client, CONFIG_PREFIX, true);
            watcher.getListenable().addListener(new PathChildrenCacheListener() {

                @Override
                public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event)
                        throws Exception {

                    System.out.println("event.getType()=" + event.getType() + ",key=" + event.getData().getPath() + ",value="
                            + new String(event.getData().getData()));
                    reloadDataSource(new String(client.getData().forPath(CONFIG_PREFIX + DRIVER_CLASS)),
                            new String(client.getData().forPath(CONFIG_PREFIX + URL)),
                            new String(client.getData().forPath(CONFIG_PREFIX + USERNAME)),
                            new String(client.getData().forPath(CONFIG_PREFIX + PASSWORD)));
                }
            });
            watcher.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void reloadDataSource(String driverClass, String url, String username, String password) throws Exception {
        DruidDataSource dataSource = SpringUtils.getBean("dataSource");
        dataSource.setUsername(username);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClass);
        dataSource.setPassword(password);
        dataSource.restart();
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        init();
    }
}
